package com.spzx.cart.service.impl;

import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    RemoteProductService remoteProductService;


    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //构建购物车的Key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        String hashKey = String.valueOf(skuId);//小key
        //判断商品是否添加过购物车
        BoundHashOperations<String,String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        int threshold =99;
        if(hashOps.hasKey(hashKey)){//添加过

            CartInfo cartInfo = hashOps.get(hashKey);
            int total = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(total>threshold?threshold:total);
            cartInfo.setUpdateTime(new Date());
            cartInfo.setCreateTime(new Date());
            hashOps.put(hashKey,cartInfo);

        }else { //首次添加
            Long size = hashOps.size();
            if(++size>50){
                throw  new ServiceException("商品不能超过50件");
            }
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUpdateTime(new Date());//使用时间,回显购物车商品倒序排序
            cartInfo.setCreateTime(new Date());
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);

            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            if(R.FAIL==productSkuResult.getCode()){ //状态码500 说明远程调用降级处理
                throw new ServiceException(productSkuResult.getMsg());//交给统一异常处理器处理
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setCartPrice(productSku.getSalePrice());//购物车价格,刚添加的价格
            cartInfo.setSkuPrice(productSku.getSalePrice());//购物车价格,商品变动后,购物车显示的价格

            cartInfo.setSkuNum(skuNum);
            cartInfo.setThumbImg(productSku.getThumbImg());
            cartInfo.setSkuName(productSku.getSkuName());
            cartInfo.setIsChecked(1);

            hashOps.put(hashKey,cartInfo);
        }
    }

    private  String getCartKey(Long userId) {
        String cartKey = "user:cart:" + userId;//大key
        return cartKey;
    }

    @Override
    public List<CartInfo> getCartList() {
        //构建购物车的Key
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> values = boundHashOperations.values();

        if (CollectionUtils.isEmpty(values)){
            return new ArrayList<>();
        }
        //需要更新的创建时间倒序
        List<CartInfo> sortedvalues =values.stream().sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime())).toList();
        //回显数据最低价格,页面给与用户提示:价格变动
        List<Long> skuIdList = sortedvalues.stream().map(CartInfo::getSkuId).toList();
        R<List<SkuPrice>> skuPriceListResult = remoteProductService.getSkuPriceList(skuIdList,SecurityConstants.INNER);

        if (R.FAIL == skuPriceListResult.getCode()){
            throw new ServiceException(skuPriceListResult.getMsg());
        }
        //List转Map
        List<SkuPrice> skuPriceList = skuPriceListResult.getData();
        Map<Long, BigDecimal> skuIdToSalePriceMap = skuPriceList.stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));

        for (CartInfo cartInfo : sortedvalues) {
            Long skuId = cartInfo.getSkuId();
            BigDecimal salePrice = skuIdToSalePriceMap.get(skuId);
            cartInfo.setSkuPrice(salePrice);
        }

        return sortedvalues;
    }

    @Override
    public void deleteCart(Long skuId) {
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);

        BoundHashOperations<String,String,CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        hashOperations.delete(skuId.toString());
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        // 修改缓存
        String cartKey = this.getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        // 先获取用户选择的商品
        if (hashOperations.hasKey(skuId.toString())) {
            CartInfo cartInfoUpd = hashOperations.get(skuId.toString());
            // cartInfoUpd 写会缓存
            cartInfoUpd.setIsChecked(isChecked);
            // 更新缓存
            hashOperations.put(skuId.toString(), cartInfoUpd);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOperations.values();

        //redisTemplate.opsForHash().values(cartKey);
        cartInfoList.forEach(item -> {
            CartInfo cartInfoUpd = hashOperations.get(item.getSkuId().toString());
            cartInfoUpd.setIsChecked(isChecked);

            // 更新缓存
            hashOperations.put(item.getSkuId().toString(), cartInfoUpd);
        });
    }

    @Override
    public void clearCart() {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartKey = getCartKey(userId);
        //获取缓存对象
        redisTemplate.delete(cartKey);
    }

    //todo 待完善
    @Override
    public List<CartInfo> getCartCheckList(Long userId) {
        ArrayList<CartInfo> cartInfoArrayList = new ArrayList<>();
        
        String cartKey = getCartKey(userId);
        List<CartInfo> cartCachInfoList = redisTemplate.opsForHash().values(cartKey);
        if(CollectionUtils.isEmpty(cartCachInfoList)){
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked().intValue()==1){
                    cartInfoArrayList.add(cartInfo);
                }
            }
        }
        return cartInfoArrayList;
    }
}